package com.pay.service.impl;

import com.pay.bean.QuickPayTradeContext;
import com.pay.entity.trans.BankInterface;
import com.pay.service.BankInterfaceService;
import com.pay.service.TransRouteHandlerMgrService;
import com.pay.util.ApplicationContextHandle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * decs:
 * Created by @hsk198
 * 2017/9/24 0024
 */
@Component
public class TransRouteManager {

    private static final Logger logger = LoggerFactory.getLogger(TransRouteManager.class);

    private ConcurrentMap<String,BankInterface> transRouteMap = new ConcurrentHashMap<String,BankInterface>();

    private Vector<TransRouteHandlerMgrService> handlers = new Vector<TransRouteHandlerMgrService>();

    @Resource
    private ApplicationContextHandle applicationContextHandle;

    @Resource(name="bankInterfaceService")
    private BankInterfaceService bankInterfaceService;

    @PostConstruct
    public void initAll() {
        try {
            logger.info("初始化接口");
            initInterface();
            logger.info("初始化规则");
            initRules();
        } catch (RuntimeException e) {
            logger.error("initAll() error", e);
        }
    }

    private void initInterface() {
        Long start = Long.valueOf(System.currentTimeMillis());
        List<BankInterface> bankInterfaces = getBankInterfaces();
        if ((null != bankInterfaces) && (bankInterfaces.size() > 0)) {
            for (BankInterface bankInterface : bankInterfaces) {
                transRouteMap.put(bankInterface.getBankInterfaceCode(), bankInterface);
            }
        }
        Long end = Long.valueOf(System.currentTimeMillis());
        logger.info("加载路由用时" + (end.longValue() - start.longValue()) + "豪秒");
    }


    private void initRules() {
        Long start = Long.valueOf(System.currentTimeMillis());
        List handlerServiceList = (List) applicationContextHandle.getBean("handlerService");
        handlers.addAll(handlerServiceList);
        Long end = Long.valueOf(System.currentTimeMillis());
        logger.info("加载规则用时" + (end.longValue() - start.longValue()) + "豪秒");
    }


    private List<BankInterface> getBankInterfaces(){
        BankInterface bankInterface = new BankInterface();
        bankInterface.setStatus("TRUE");
        return this.bankInterfaceService.selectBankInterfacesByStatus(bankInterface);
    }


    public void reloadRouteAll() {
        initAll();
    }


    public BankInterface getRoute(String bankInterfaceCode)   {
        return (BankInterface)transRouteMap.get(bankInterfaceCode);
    }


    public BankInterface getRoute(QuickPayTradeContext tradeContext)   {
        Long start = Long.valueOf(System.currentTimeMillis());
        //遍历接口
        List<BankInterface> tempList = new ArrayList<BankInterface>();
        BankInterface finalInterface = null;
        Iterator bankInterfaceIt = transRouteMap.keySet().iterator();
        while(bankInterfaceIt.hasNext()){
            String key = (String) bankInterfaceIt.next();
            BankInterface bankInterface = transRouteMap.get(key);
            tradeContext.setBankInterface(bankInterface);
            //业务规则筛选
            boolean routeFlag = false;
            for (TransRouteHandlerMgrService transRouteHandlerMgrService : this.handlers) {
                if (!transRouteHandlerMgrService.rulesHandler(tradeContext)) {
                    routeFlag = true;
                    break;
                }
            }

            if (!routeFlag){
                //可用通道权重及优先级选择
                tempList.add(bankInterface);
            }
        }
        if(null!=tempList && !tempList.isEmpty()){
            finalInterface  = checkBankInterfaceInfo(tempList);//权重 优先级 TOTAL匹配
        }
        Long end = Long.valueOf(System.currentTimeMillis());
        logger.info("调用路由用时" + (end.longValue() - start.longValue()) + "豪秒");
        return finalInterface;
    }


    private BankInterface checkBankInterfaceInfo(List<BankInterface> list){

        return null;
    }

}
